/*
 * Condition.h
 *
 *  Created on: 01.10.2012
 *      Author: Lapchinskiy
 */
#include "Global_types.h"
#include "BuildConfig.h"
#include "Logging.h"
#include "ArrayList.h"
#include "ConditionVariable.h"
#include "stdarg.h"
#ifndef CONDITION_H_
#define CONDITION_H_
//#include "Global_includes.h"
template<class T>
class Condition {
public:
	Condition();
	~Condition();
	Condition(int operandNum, ...);
	Condition(T* firstOperand,T(ConditionVariable<T>::*)(T*),T* secondOperand,bool (ConditionVariable<T>::*)(T*),T* checkVal);
	bool check();
	bool checkInt();
private:
	T(ConditionVariable<T>::*opFunc)(T*);
	ConditionVariable<T> *checkValue;
	ArrayList<ConditionVariable<T> > *conVarList;
	ArrayList<T(ConditionVariable<T>::*)(T*)> *operatorList;
	bool (ConditionVariable<T>::*logicOperator)(T*);
};

template<class T>
Condition<T>::Condition(int operandNum, ...) {
	conVarList = new ArrayList<ConditionVariable<T> >();
	operatorList = new ArrayList<T(ConditionVariable<T>::*)(T*)>();
	va_list vl;
	va_start(vl, (operandNum*2+1));

	for (uint8_t i = 0; i < operandNum - 1; i++) {
		conVarList->add(new ConditionVariable<T>(va_arg(vl,T*)));
		opFunc = va_arg(vl,T(ConditionVariable<T>::*)(T*));
		operatorList->add(&opFunc);
	}
	conVarList->add(new ConditionVariable<T>(va_arg(vl,T*)));
	logicOperator = va_arg(vl,bool (ConditionVariable<T>::*)(T*));
	checkValue = new ConditionVariable<T>(va_arg(vl,T*));
	va_end(vl);

}

template<class T>
Condition<T>::Condition(T* firstOperand,T(ConditionVariable<T>::*pOpFunc)(T*),T* secondOperand,bool (ConditionVariable<T>::*logicOp)(T*),T* checkVal) {
	conVarList = new ArrayList<ConditionVariable<T> >();
	operatorList = new ArrayList<T(ConditionVariable<T>::*)(T*)>();
		conVarList->add(new ConditionVariable<T>(firstOperand));
		opFunc =pOpFunc;
		operatorList->add(&opFunc);
	conVarList->add(new ConditionVariable<T>(secondOperand));
	logicOperator = logicOp;
	checkValue = new ConditionVariable<T>(checkVal);

}
template<class T>
inline Condition<T>::Condition() {
}

template<class T>
bool Condition<T>::check() {
	bool checkResult;
	T tempVar;
	ConditionVariable<T> *temp = new ConditionVariable<T>
			(&tempVar);
	tempVar =*(conVarList->get(0)->getValue());
	for (uint8_t i = 1; i < conVarList->getLength(); i++) {

		tempVar=(temp->**operatorList->get(i-1))(
				(conVarList->get(i))->getValue());
	}
	checkResult = (temp->*logicOperator)(checkValue->getValue());
	delete temp;
	return checkResult;

}

template<class T>
Condition<T>::~Condition() {
	delete conVarList;
	delete operatorList;
	delete checkValue;
}

#endif /* CONDITION_H_ */
